home *** CD-ROM | disk | FTP | other *** search
/ Chip 2002 June / Chip_2002-06_cd1.bin / zkuste / delphi / kolekce / d6 / rxlibsetup.exe / {app} / units / Rxslider.pas < prev    next >
Encoding:
Pascal/Delphi Source File  |  2002-02-19  |  35.2 KB  |  1,206 lines

  1. {*******************************************************}
  2. {                                                       }
  3. {         Delphi VCL Extensions (RX)                    }
  4. {                                                       }
  5. {         Copyright (c) 2001,2002 SGB Software          }
  6. {         Copyright (c) 1997, 1998 Fedor Koshevnikov,   }
  7. {                        Igor Pavluk and Serge Korolev  }
  8. {                                                       }
  9. {*******************************************************}
  10.  
  11.  
  12. unit RXSlider;
  13.  
  14. interface
  15.  
  16. {$I RX.INC}
  17.  
  18. uses {$IFDEF WIN32} Windows, {$ELSE} WinTypes, WinProcs, {$ENDIF}
  19.   Controls, ExtCtrls, Classes, Graphics, Messages, Menus;
  20.  
  21. type
  22.   TNumThumbStates = 1..2;
  23.   TSliderOrientation = (soHorizontal, soVertical);
  24.   TSliderOption = (soShowFocus, soShowPoints, soSmooth,
  25.     soRulerOpaque, soThumbOpaque);
  26.   TSliderOptions = set of TSliderOption;
  27.   TSliderImage = (siHThumb, siHRuler, siVThumb, siVRuler);
  28.   TSliderImages = set of TSliderImage;
  29.   TSliderImageArray = array[TSliderImage] of TBitmap;
  30.   TJumpMode = (jmNone, jmHome, jmEnd, jmNext, jmPrior);
  31.  
  32. { TRxCustomSlider }
  33.  
  34.   TRxCustomSlider = class(TCustomControl)
  35.   private
  36.     FUserImages: TSliderImages;
  37.     FImages: TSliderImageArray;
  38.     FEdgeSize: Integer;
  39.     FRuler: TBitmap;
  40.     FPaintBuffered: Boolean;
  41.     FRulerOrg: TPoint;
  42.     FThumbRect: TRect;
  43.     FThumbDown: Boolean;
  44.     FNumThumbStates: TNumThumbStates;
  45.     FPointsRect: TRect;
  46.     FOrientation: TSliderOrientation;
  47.     FOptions: TSliderOptions;
  48.     FBevelStyle: TPanelBevel;
  49.     FBevelWidth: Integer;
  50.     FMinValue: Longint;
  51.     FMaxValue: Longint;
  52.     FIncrement: Longint;
  53.     FValue: Longint;
  54.     FHit: Integer;
  55.     FFocused: Boolean;
  56.     FSliding: Boolean;
  57.     FTracking: Boolean;
  58.     FTimerActive: Boolean;
  59.     FMousePos: TPoint;
  60.     FStartJump: TJumpMode;
  61.     FReadOnly: Boolean;
  62.     FOnChange: TNotifyEvent;
  63.     FOnChanged: TNotifyEvent;
  64.     FOnDrawPoints: TNotifyEvent;
  65.     function GetImage(Index: Integer): TBitmap;
  66.     procedure SetImage(Index: Integer; Value: TBitmap);
  67.     procedure SliderImageChanged(Sender: TObject);
  68.     procedure SetEdgeSize(Value: Integer);
  69.     function GetNumThumbStates: TNumThumbStates;
  70.     procedure SetNumThumbStates(Value: TNumThumbStates);
  71.     procedure SetBevelStyle(Value: TPanelBevel);
  72.     procedure SetOrientation(Value: TSliderOrientation);
  73.     procedure SetOptions(Value: TSliderOptions);
  74.     procedure SetMinValue(Value: Longint);
  75.     procedure SetMaxValue(Value: Longint);
  76.     procedure SetIncrement(Value: Longint);
  77.     procedure SetReadOnly(Value: Boolean);
  78.     function GetThumbOffset: Integer;
  79.     procedure SetThumbOffset(Value: Integer);
  80.     procedure SetValue(Value: Longint);
  81.     procedure ThumbJump(Jump: TJumpMode);
  82.     function GetThumbPosition(var Offset: Integer): TPoint;
  83.     function JumpTo(X, Y: Integer): TJumpMode;
  84.     procedure InvalidateThumb;
  85.     procedure StopTracking;
  86.     procedure TimerTrack;
  87.     function StoreImage(Index: Integer): Boolean;
  88.     procedure CreateElements;
  89.     procedure BuildRuler(R: TRect);
  90.     procedure AdjustElements;
  91.     procedure ReadUserImages(Stream: TStream);
  92.     procedure WriteUserImages(Stream: TStream);
  93.     procedure InternalDrawPoints(ACanvas: TCanvas; PointsStep, PointsHeight,
  94.       ExtremePointsHeight: Longint);
  95.     procedure DrawThumb(Canvas: TCanvas; Origin: TPoint; Highlight: Boolean);
  96.     function GetValueByOffset(Offset: Integer): Longint;
  97.     function GetOffsetByValue(Value: Longint): Integer;
  98.     function GetRulerLength: Integer;
  99.     procedure CMEnabledChanged(var Message: TMessage); message CM_ENABLEDCHANGED;
  100.     procedure CMFocusChanged(var Message: TCMFocusChanged); message CM_FOCUSCHANGED;
  101.     procedure WMGetDlgCode(var Msg: TWMGetDlgCode); message WM_GETDLGCODE;
  102.     procedure WMPaint(var Message: TWMPaint); message WM_PAINT;
  103.     procedure WMSetCursor(var Message: TWMSetCursor); message WM_SETCURSOR;
  104.     procedure WMSize(var Message: TWMSize); message WM_SIZE;
  105.     procedure WMTimer(var Message: TMessage); message WM_TIMER;
  106.   protected
  107.     procedure AlignControls(AControl: TControl; var Rect: TRect); override;
  108.     procedure DefineProperties(Filer: TFiler); override;
  109.     procedure KeyDown(var Key: Word; Shift: TShiftState); override;
  110.     procedure Loaded; override;
  111.     procedure MouseDown(Button: TMouseButton; Shift: TShiftState;
  112.       X, Y: Integer); override;
  113.     procedure MouseMove(Shift: TShiftState; X, Y: Integer); override;
  114.     procedure MouseUp(Button: TMouseButton; Shift: TShiftState;
  115.       X, Y: Integer); override;
  116.     procedure Paint; override;
  117.     function CanModify: Boolean; virtual;
  118.     function GetSliderRect: TRect; virtual;
  119.     function GetSliderValue: Longint; virtual;
  120.     procedure Change; dynamic;
  121.     procedure Changed; dynamic;
  122.     procedure Sized; virtual;
  123.     procedure RangeChanged; virtual;
  124.     procedure SetRange(Min, Max: Longint);
  125.     procedure ThumbMouseDown(Button: TMouseButton; Shift: TShiftState;
  126.       X, Y: Integer); virtual;
  127.     procedure ThumbMouseMove(Shift: TShiftState; X, Y: Integer); virtual;
  128.     procedure ThumbMouseUp(Button: TMouseButton; Shift: TShiftState;
  129.       X, Y: Integer); virtual;
  130.     property ThumbOffset: Integer read GetThumbOffset write SetThumbOffset;
  131.     property SliderRect: TRect read GetSliderRect;
  132.     property BevelStyle: TPanelBevel read FBevelStyle write SetBevelStyle
  133.       default bvNone;
  134.     property ImageHThumb: TBitmap index Ord(siHThumb) read GetImage
  135.       write SetImage stored StoreImage;
  136.     property ImageHRuler: TBitmap index Ord(siHRuler) read GetImage
  137.       write SetImage  stored StoreImage;
  138.     property ImageVThumb: TBitmap index Ord(siVThumb) read GetImage
  139.       write SetImage stored StoreImage;
  140.     property ImageVRuler: TBitmap index Ord(siVRuler) read GetImage
  141.       write SetImage stored StoreImage;
  142.     property NumThumbStates: TNumThumbStates read GetNumThumbStates
  143.       write SetNumThumbStates default 2;
  144.     property Orientation: TSliderOrientation read FOrientation
  145.       write SetOrientation default soHorizontal;
  146.     property EdgeSize: Integer read FEdgeSize write SetEdgeSize default 2;
  147.     property Options: TSliderOptions read FOptions write SetOptions
  148.       default [soShowFocus, soShowPoints, soSmooth];
  149.     property ReadOnly: Boolean read FReadOnly write SetReadOnly default False;
  150.     property OnChange: TNotifyEvent read FOnChange write FOnChange;
  151.     property OnChanged: TNotifyEvent read FOnChanged write FOnChanged;
  152.     property OnDrawPoints: TNotifyEvent read FOnDrawPoints write FOnDrawPoints;
  153.   public
  154.     constructor Create(AOwner: TComponent); override;
  155.     destructor Destroy; override;
  156.     procedure DefaultDrawPoints(PointsStep, PointsHeight,
  157.       ExtremePointsHeight: Longint); virtual;
  158.     property Canvas;
  159.     property Increment: Longint read FIncrement write SetIncrement default 10;
  160.     property MinValue: Longint read FMinValue write SetMinValue default 0;
  161.     property MaxValue: Longint read FMaxValue write SetMaxValue default 100;
  162.     property Value: Longint read FValue write SetValue default 0;
  163.   end;
  164.  
  165. { TRxSlider }
  166.  
  167.   TRxSlider = class(TRxCustomSlider)
  168.   published
  169.     property Align;
  170.     property BevelStyle;
  171.     property Color;
  172.     property Cursor;
  173.     property DragMode;
  174.     property DragCursor;
  175.     property Enabled;
  176.     property ImageHThumb;
  177.     property ImageHRuler;
  178.     property ImageVThumb;
  179.     property ImageVRuler;
  180.     property Increment;
  181.     property MinValue;
  182.     property MaxValue;
  183.     property NumThumbStates;
  184.     property Orientation;
  185.     { ensure Orientation is published before EdgeSize }
  186.     property EdgeSize;
  187.     property Options;
  188.     property ParentColor;
  189.     property ParentShowHint;
  190.     property PopupMenu;
  191.     property ShowHint;
  192.     property TabOrder;
  193.     property TabStop default True;
  194.     property Value;
  195.     property Visible;
  196. {$IFDEF RX_D4}
  197.     property Anchors;
  198.     property Constraints;
  199.     property DragKind;
  200. {$ENDIF}
  201.     property OnChange;
  202.     property OnChanged;
  203.     property OnDrawPoints;
  204.     property OnClick;
  205.     property OnDblClick;
  206.     property OnEnter;
  207.     property OnExit;
  208.     property OnMouseMove;
  209.     property OnMouseDown;
  210.     property OnMouseUp;
  211.     property OnKeyDown;
  212.     property OnKeyUp;
  213.     property OnKeyPress;
  214.     property OnDragOver;
  215.     property OnDragDrop;
  216.     property OnEndDrag;
  217. {$IFDEF WIN32}
  218.     property OnStartDrag;
  219. {$ENDIF}
  220. {$IFDEF RX_D5}
  221.     property OnContextPopup;
  222. {$ENDIF}
  223. {$IFDEF RX_D4}
  224.     property OnMouseWheelDown;
  225.     property OnMouseWheelUp;
  226.     property OnEndDock;
  227.     property OnStartDock;
  228. {$ENDIF}
  229.   end;
  230.  
  231. { TRxCustomTrackBar }
  232.  
  233.   TRxSliderImages = class;
  234.  
  235.   TRxCustomTrackBar = class(TRxCustomSlider)
  236.   private
  237.     FImages: TRxSliderImages;
  238.   protected
  239.     property Images: TRxSliderImages read FImages write FImages;
  240.   public
  241.     constructor Create(AOwner: TComponent); override;
  242.     destructor Destroy; override;
  243.   end;
  244.  
  245.   TRxSliderImages = class(TPersistent)
  246.   private
  247.     FSlider: TRxCustomSlider;
  248.     function GetNumThumbStates: TNumThumbStates;
  249.     procedure SetNumThumbStates(Value: TNumThumbStates);
  250.     function GetEdgeSize: Integer;
  251.     procedure SetEdgeSize(Value: Integer);
  252.     function GetImage(Index: Integer): TBitmap;
  253.     procedure SetImage(Index: Integer; Value: TBitmap);
  254.     function StoreImage(Index: Integer): Boolean;
  255.   published
  256.     property HorzThumb: TBitmap index Ord(siHThumb) read GetImage
  257.       write SetImage stored StoreImage;
  258.     property HorzRuler: TBitmap index Ord(siHRuler) read GetImage
  259.       write SetImage stored StoreImage;
  260.     property VertThumb: TBitmap index Ord(siVThumb) read GetImage
  261.       write SetImage stored StoreImage;
  262.     property VertRuler: TBitmap index Ord(siVRuler) read GetImage
  263.       write SetImage stored StoreImage;
  264.     property NumThumbStates: TNumThumbStates read GetNumThumbStates
  265.       write SetNumThumbStates default 2;
  266.     property EdgeSize: Integer read GetEdgeSize write SetEdgeSize default 2;
  267.   end;
  268.  
  269. implementation
  270.  
  271. uses Consts, Forms, SysUtils, VCLUtils, MaxMin, RxConst;
  272.  
  273. {$IFDEF WIN32}
  274.  {$R *.R32}
  275. {$ELSE}
  276.  {$R *.R16}
  277. {$ENDIF}
  278.  
  279. const
  280.   ImagesResNames: array[TSliderImage] of PChar =
  281.     ('W95_HTB', 'W95_HRL', 'W95_VTB', 'W95_VRL');
  282.   Indent = 6;
  283.   JumpInterval = 400;
  284.  
  285. { TRxCustomSlider }
  286.  
  287. constructor TRxCustomSlider.Create(AOwner: TComponent);
  288. begin
  289.   inherited Create(AOwner);
  290.   ControlState := ControlState + [csCreating];
  291.   ControlStyle := [csClickEvents, csCaptureMouse, csAcceptsControls,
  292.     csDoubleClicks, csOpaque];
  293.   Width := 150;
  294.   Height := 40;
  295.   FNumThumbStates := 2;
  296.   FBevelWidth := 1;
  297.   FOrientation := soHorizontal;
  298.   FOptions := [soShowFocus, soShowPoints, soSmooth];
  299.   FEdgeSize := 2;
  300.   FMinValue := 0;
  301.   FMaxValue := 100;
  302.   FIncrement := 10;
  303.   TabStop := True;
  304.   CreateElements;
  305.   ControlState := ControlState - [csCreating];
  306. end;
  307.  
  308. destructor TRxCustomSlider.Destroy;
  309. var
  310.   I: TSliderImage;
  311. begin
  312.   FOnChange := nil;
  313.   FOnChanged := nil;
  314.   FOnDrawPoints := nil;
  315.   FRuler.Free;
  316.   for I := Low(FImages) to High(FImages) do begin
  317.     FImages[I].OnChange := nil;
  318.     FImages[I].Free;
  319.   end;
  320.   inherited Destroy;
  321. end;
  322.  
  323. procedure TRxCustomSlider.Loaded;
  324. var
  325.   I: TSliderImage;
  326. begin
  327.   inherited Loaded;
  328.   for I := Low(FImages) to High(FImages) do
  329.     if I in FUserImages then SetImage(Ord(I), FImages[I]);
  330. end;
  331.  
  332. procedure TRxCustomSlider.AlignControls(AControl: TControl; var Rect: TRect);
  333. var
  334.   BevelSize: Integer;
  335. begin
  336.   BevelSize := 0;
  337.   if BevelStyle <> bvNone then Inc(BevelSize, FBevelWidth);
  338.   InflateRect(Rect, -BevelSize, -BevelSize);
  339.   inherited AlignControls(AControl, Rect);
  340. end;
  341.  
  342. procedure TRxCustomSlider.WMPaint(var Message: TWMPaint);
  343. var
  344.   DC, MemDC: HDC;
  345.   MemBitmap, OldBitmap: HBITMAP;
  346.   PS: TPaintStruct;
  347. begin
  348.   if FPaintBuffered then inherited
  349.   else begin
  350. {$IFDEF RX_D3}
  351.     Canvas.Lock;
  352.     try
  353. {$ENDIF}
  354.       MemDC := GetDC(0);
  355.       MemBitmap := CreateCompatibleBitmap(MemDC, ClientWidth, ClientHeight);
  356.       ReleaseDC(0, MemDC);
  357.       MemDC := CreateCompatibleDC(0);
  358.       OldBitmap := SelectObject(MemDC, MemBitmap);
  359.       try
  360.         DC := Message.DC;
  361.         Perform(WM_ERASEBKGND, MemDC, MemDC);
  362.         FPaintBuffered := True;
  363.         Message.DC := MemDC;
  364.         try
  365.           WMPaint(Message);
  366.         finally
  367.           Message.DC := DC;
  368.           FPaintBuffered := False;
  369.         end;
  370.         if DC = 0 then DC := BeginPaint(Handle, PS);
  371.         BitBlt(DC, 0, 0, ClientWidth, ClientHeight, MemDC, 0, 0, SRCCOPY);
  372.         if Message.DC = 0 then EndPaint(Handle, PS);
  373.       finally
  374.         SelectObject(MemDC, OldBitmap);
  375.         DeleteDC(MemDC);
  376.         DeleteObject(MemBitmap);
  377.       end;
  378. {$IFDEF RX_D3}
  379.     finally
  380.       Canvas.Unlock;
  381.     end;
  382. {$ENDIF}
  383.   end;
  384. end;
  385.  
  386. procedure TRxCustomSlider.Paint;
  387. var
  388.   R: TRect;
  389.   TopColor, BottomColor, TransColor: TColor;
  390.   HighlightThumb: Boolean;
  391.   P: TPoint;
  392. {$IFDEF WIN32}
  393.   Offset: Integer;
  394. {$ENDIF}
  395. begin
  396. {$IFDEF WIN32}
  397.   if csPaintCopy in ControlState then begin
  398.     Offset := GetOffsetByValue(GetSliderValue);
  399.     P := GetThumbPosition(Offset);
  400.   end else
  401. {$ENDIF}
  402.   P := Point(FThumbRect.Left, FThumbRect.Top);
  403.   R := GetClientRect;
  404.   if BevelStyle <> bvNone then begin
  405.     TopColor := clBtnHighlight;
  406.     if BevelStyle = bvLowered then TopColor := clBtnShadow;
  407.     BottomColor := clBtnShadow;
  408.     if BevelStyle = bvLowered then BottomColor := clBtnHighlight;
  409.     Frame3D(Canvas, R, TopColor, BottomColor, FBevelWidth);
  410.   end;
  411.   if (csOpaque in ControlStyle) then
  412.     with Canvas do begin
  413.       Brush.Color := Color;
  414.       FillRect(R);
  415.     end;
  416.   if FRuler.Width > 0 then begin
  417.     if soRulerOpaque in Options then TransColor := clNone
  418.     else TransColor := FRuler.TransparentColor;
  419.     DrawBitmapTransparent(Canvas, FRulerOrg.X, FRulerOrg.Y, FRuler,
  420.       TransColor);
  421.   end;
  422.   if (soShowFocus in Options) and FFocused and
  423.     not (csDesigning in ComponentState) then
  424.   begin
  425.     R := SliderRect;
  426.     InflateRect(R, -2, -2);
  427.     Canvas.DrawFocusRect(R);
  428.   end;
  429.   if (soShowPoints in Options) then begin
  430.     if Assigned(FOnDrawPoints) then FOnDrawPoints(Self)
  431.     else InternalDrawPoints(Canvas, Increment, 3, 5);
  432.   end;
  433. {$IFDEF WIN32}
  434.   if csPaintCopy in ControlState then
  435.     HighlightThumb := not Enabled else
  436. {$ENDIF}
  437.   HighlightThumb := FThumbDown or not Enabled;
  438.   DrawThumb(Canvas, P, HighlightThumb);
  439. end;
  440.  
  441. function TRxCustomSlider.CanModify: Boolean;
  442. begin
  443.   Result := True;
  444. end;
  445.  
  446. function TRxCustomSlider.GetSliderValue: Longint;
  447. begin
  448.   Result := FValue;
  449. end;
  450.  
  451. function TRxCustomSlider.GetSliderRect: TRect;
  452. begin
  453.   Result := Bounds(0, 0, Width, Height);
  454.   if BevelStyle <> bvNone then
  455.     InflateRect(Result, -FBevelWidth, -FBevelWidth);
  456. end;
  457.  
  458. procedure TRxCustomSlider.DrawThumb(Canvas: TCanvas; Origin: TPoint;
  459.   Highlight: Boolean);
  460. var
  461.   R: TRect;
  462.   Image: TBitmap;
  463.   TransColor: TColor;
  464. begin
  465.   if Orientation = soHorizontal then Image := ImageHThumb
  466.   else Image := ImageVThumb;
  467.   R := Rect(0, 0, Image.Width, Image.Height);
  468.   if NumThumbStates = 2 then begin
  469.     if Highlight then R.Left := (R.Right - R.Left) div 2
  470.     else R.Right := (R.Right - R.Left) div 2;
  471.   end;
  472.   if soThumbOpaque in Options then TransColor := clNone
  473.   else TransColor := Image.TransparentColor;
  474.   DrawBitmapRectTransparent(Canvas, Origin.X, Origin.Y, R, Image, TransColor);
  475. end;
  476.  
  477. procedure TRxCustomSlider.InternalDrawPoints(ACanvas: TCanvas; PointsStep,
  478.   PointsHeight, ExtremePointsHeight: Longint);
  479. const
  480.   MinInterval = 3;
  481. var
  482.   RulerLength: Integer;
  483.   Interval, Scale, PointsCnt, I, Val: Longint;
  484.   X, H, X1, X2, Y1, Y2: Integer;
  485.   Range: Double;
  486. begin
  487.   RulerLength := GetRulerLength;
  488.   ACanvas.Pen.Color := clWindowText;
  489.   Scale := 0;
  490.   Range := MaxValue - MinValue;
  491.   repeat
  492.     Inc(Scale);
  493.     PointsCnt := Round(Range / (Scale * PointsStep)) + 1;
  494.     if PointsCnt > 1 then
  495.       Interval := RulerLength div (PointsCnt - 1)
  496.     else Interval := RulerLength;
  497.   until (Interval >= MinInterval + 1) or (Interval >= RulerLength);
  498.   Val := MinValue;
  499.   for I := 1 to PointsCnt do begin
  500.     H := PointsHeight;
  501.     if I = PointsCnt then Val := MaxValue;
  502.     if (Val = MaxValue) or (Val = MinValue) then H := ExtremePointsHeight;
  503.     X := GetOffsetByValue(Val);
  504.     if Orientation = soHorizontal then begin
  505.       X1 := X + (FImages[siHThumb].Width div NumThumbStates) div 2;
  506.       Y1 := FPointsRect.Top;
  507.       X2 := X1;
  508.       Y2 := Y1 + H;
  509.     end
  510.     else begin
  511.       X1 := FPointsRect.Left;
  512.       Y1 := X + FImages[siVThumb].Height div 2;
  513.       X2 := X1 + H;
  514.       Y2 := Y1;
  515.     end;
  516.     with ACanvas do begin
  517.       MoveTo(X1, Y1);
  518.       LineTo(X2, Y2);
  519.     end;
  520.     Inc(Val, Scale * PointsStep);
  521.   end;
  522. end;
  523.  
  524. procedure TRxCustomSlider.DefaultDrawPoints(PointsStep, PointsHeight,
  525.   ExtremePointsHeight: Longint);
  526. begin
  527.   InternalDrawPoints(Canvas, PointsStep, PointsHeight, ExtremePointsHeight);
  528. end;
  529.  
  530. procedure TRxCustomSlider.CreateElements;
  531. var
  532.   I: TSliderImage;
  533. begin
  534.   FRuler := TBitmap.Create;
  535.   for I := Low(FImages) to High(FImages) do SetImage(Ord(I), nil);
  536.   AdjustElements;
  537. end;
  538.  
  539. procedure TRxCustomSlider.BuildRuler(R: TRect);
  540. var
  541.   DstR, BmpR: TRect;
  542.   I, L, B, N, C, Offs, Len, RulerWidth: Integer;
  543.   TmpBmp: TBitmap;
  544.   Index: TSliderImage;
  545. begin
  546.   TmpBmp := TBitmap.Create;
  547.   try
  548.     if Orientation = soHorizontal then Index := siHRuler
  549.     else Index := siVRuler;
  550.     if Orientation = soHorizontal then begin
  551.       L := R.Right - R.Left - 2 * Indent;
  552.       if L < 0 then L := 0;
  553.       TmpBmp.Width := L;
  554.       TmpBmp.Height := FImages[Index].Height;
  555.       L := TmpBmp.Width - 2 * FEdgeSize;
  556.       B := FImages[Index].Width - 2 * FEdgeSize;
  557.       RulerWidth := FImages[Index].Width;
  558.     end
  559.     else begin
  560.       TmpBmp.Width := FImages[Index].Width;
  561.       TmpBmp.Height := R.Bottom - R.Top - 2 * Indent;
  562.       L := TmpBmp.Height - 2 * FEdgeSize;
  563.       B := FImages[Index].Height - 2 * FEdgeSize;
  564.       RulerWidth := FImages[Index].Height;
  565.     end;
  566.     N := (L div B) + 1;
  567.     C := L mod B;
  568.     for I := 0 to N - 1 do begin
  569.       if I = 0 then begin
  570.         Offs := 0;
  571.         Len := RulerWidth - FEdgeSize;
  572.       end
  573.       else begin
  574.         Offs := FEdgeSize + I * B;
  575.         if I = N - 1 then Len := C + FEdgeSize
  576.         else Len := B;
  577.       end;
  578.       if Orientation = soHorizontal then
  579.         DstR := Rect(Offs, 0, Offs + Len, TmpBmp.Height)
  580.       else DstR := Rect(0, Offs, TmpBmp.Width, Offs + Len);
  581.       if I = 0 then Offs := 0
  582.       else
  583.         if I = N - 1 then Offs := FEdgeSize + B - C
  584.         else Offs := FEdgeSize;
  585.       if Orientation = soHorizontal then
  586.         BmpR := Rect(Offs, 0, Offs + DstR.Right - DstR.Left, TmpBmp.Height)
  587.       else
  588.         BmpR := Rect(0, Offs, TmpBmp.Width, Offs + DstR.Bottom - DstR.Top);
  589.       TmpBmp.Canvas.CopyRect(DstR, FImages[Index].Canvas, BmpR);
  590.     end;
  591.     FRuler.Assign(TmpBmp);
  592.   finally
  593.     TmpBmp.Free;
  594.   end;
  595. end;
  596.  
  597. procedure TRxCustomSlider.AdjustElements;
  598. var
  599.   SaveValue: Longint;
  600.   R: TRect;
  601. begin
  602.   SaveValue := Value;
  603.   R := SliderRect;
  604.   BuildRuler(R);
  605.   if Orientation = soHorizontal then begin
  606.     if FImages[siHThumb].Height > FRuler.Height then begin
  607.       FThumbRect := Bounds(R.Left + Indent, R.Top + Indent,
  608.         FImages[siHThumb].Width div NumThumbStates, FImages[siHThumb].Height);
  609.       FRulerOrg := Point(R.Left + Indent, R.Top + Indent +
  610.         (FImages[siHThumb].Height - FRuler.Height) div 2);
  611.       FPointsRect := Rect(FRulerOrg.X, R.Top + Indent +
  612.         FImages[siHThumb].Height + 1,
  613.         FRulerOrg.X + FRuler.Width, R.Bottom - R.Top - 1);
  614.     end
  615.     else begin
  616.       FThumbRect := Bounds(R.Left + Indent, R.Top + Indent +
  617.         (FRuler.Height - FImages[siHThumb].Height) div 2,
  618.         FImages[siHThumb].Width div NumThumbStates, FImages[siHThumb].Height);
  619.       FRulerOrg := Point(R.Left + Indent, R.Top + Indent);
  620.       FPointsRect := Rect(FRulerOrg.X, R.Top + Indent + FRuler.Height + 1,
  621.         FRulerOrg.X + FRuler.Width, R.Bottom - R.Top - 1);
  622.     end;
  623.   end
  624.   else begin { soVertical }
  625.     if FImages[siVThumb].Width div NumThumbStates > FRuler.Width then
  626.     begin
  627.       FThumbRect := Bounds(R.Left + Indent, R.Top + Indent,
  628.         FImages[siVThumb].Width div NumThumbStates, FImages[siVThumb].Height);
  629.       FRulerOrg := Point(R.Left + Indent + (FImages[siVThumb].Width div NumThumbStates -
  630.         FRuler.Width) div 2, R.Top + Indent);
  631.       FPointsRect := Rect(R.Left + Indent + FImages[siVThumb].Width div NumThumbStates + 1,
  632.         FRulerOrg.Y, R.Right - R.Left - 1, FRulerOrg.Y + FRuler.Height);
  633.     end
  634.     else begin
  635.       FThumbRect := Bounds(R.Left + Indent + (FRuler.Width -
  636.         FImages[siVThumb].Width div NumThumbStates) div 2, R.Top + Indent,
  637.         FImages[siVThumb].Width div NumThumbStates, FImages[siVThumb].Height);
  638.       FRulerOrg := Point(R.Left + Indent, R.Top + Indent);
  639.       FPointsRect := Rect(R.Left + Indent + FRuler.Width + 1, FRulerOrg.Y,
  640.         R.Right - R.Left - 1, FRulerOrg.Y + FRuler.Height);
  641.     end;
  642.   end;
  643.   Value := SaveValue;
  644.   Invalidate;
  645. end;
  646.  
  647. procedure TRxCustomSlider.Sized;
  648. begin
  649.   AdjustElements;
  650. end;
  651.  
  652. procedure TRxCustomSlider.Change;
  653. begin
  654.   if Assigned(FOnChange) then FOnChange(Self);
  655. end;
  656.  
  657. procedure TRxCustomSlider.Changed;
  658. begin
  659.   if Assigned(FOnChanged) then FOnChanged(Self);
  660. end;
  661.  
  662. procedure TRxCustomSlider.RangeChanged;
  663. begin
  664. end;
  665.  
  666. procedure TRxCustomSlider.DefineProperties(Filer: TFiler);
  667.  
  668. {$IFDEF WIN32}
  669.   function DoWrite: Boolean;
  670.   begin
  671.     if Assigned(Filer.Ancestor) then
  672.       Result := FUserImages <> TRxCustomSlider(Filer.Ancestor).FUserImages
  673.     else Result := FUserImages <> [];
  674.   end;
  675. {$ENDIF}
  676.  
  677. begin
  678.   if Filer is TReader then inherited DefineProperties(Filer);
  679.   Filer.DefineBinaryProperty('UserImages', ReadUserImages, WriteUserImages,
  680.     {$IFDEF WIN32} DoWrite {$ELSE} FUserImages <> [] {$ENDIF});
  681. end;
  682.  
  683. procedure TRxCustomSlider.ReadUserImages(Stream: TStream);
  684. begin
  685.   Stream.ReadBuffer(FUserImages, SizeOf(FUserImages));
  686. end;
  687.  
  688. procedure TRxCustomSlider.WriteUserImages(Stream: TStream);
  689. begin
  690.   Stream.WriteBuffer(FUserImages, SizeOf(FUserImages));
  691. end;
  692.  
  693. function TRxCustomSlider.StoreImage(Index: Integer): Boolean;
  694. begin
  695.   Result := TSliderImage(Index) in FUserImages;
  696. end;
  697.  
  698. function TRxCustomSlider.GetImage(Index: Integer): TBitmap;
  699. begin
  700.   Result := FImages[TSliderImage(Index)];
  701. end;
  702.  
  703. procedure TRxCustomSlider.SliderImageChanged(Sender: TObject);
  704. begin
  705.   if not (csCreating in ControlState) then Sized;
  706. end;
  707.  
  708. procedure TRxCustomSlider.SetImage(Index: Integer; Value: TBitmap);
  709. var
  710.   Idx: TSliderImage;
  711. begin
  712.   Idx := TSliderImage(Index);
  713.   if FImages[Idx] = nil then begin
  714.     FImages[Idx] := TBitmap.Create;
  715.     FImages[Idx].OnChange := SliderImageChanged;
  716.   end;
  717.   if Value = nil then begin
  718.     FImages[Idx].Handle := LoadBitmap(HInstance, ImagesResNames[Idx]);
  719.     Exclude(FUserImages, Idx);
  720.     if not (csReading in ComponentState) then begin
  721.       if Idx in [siHThumb, siVThumb] then Exclude(FOptions, soThumbOpaque)
  722.       else Exclude(FOptions, soRulerOpaque);
  723.       Invalidate;
  724.     end;
  725.   end
  726.   else begin
  727.     FImages[Idx].Assign(Value);
  728.     Include(FUserImages, Idx);
  729.   end;
  730. end;
  731.  
  732. procedure TRxCustomSlider.SetEdgeSize(Value: Integer);
  733. var
  734.   MaxSize: Integer;
  735. begin
  736.   if Orientation = soHorizontal then MaxSize := FImages[siHRuler].Width
  737.   else MaxSize := FImages[siVRuler].Height;
  738.   if Value * 2 < MaxSize then
  739.     if Value <> FEdgeSize then begin
  740.       FEdgeSize := Value;
  741.       Sized;
  742.     end;
  743. end;
  744.  
  745. function TRxCustomSlider.GetNumThumbStates: TNumThumbStates;
  746. begin
  747.   Result := FNumThumbStates;
  748. end;
  749.  
  750. procedure TRxCustomSlider.SetNumThumbStates(Value: TNumThumbStates);
  751. begin
  752.   if FNumThumbStates <> Value then begin
  753.     FNumThumbStates := Value;
  754.     AdjustElements;
  755.   end;
  756. end;
  757.  
  758. procedure TRxCustomSlider.SetBevelStyle(Value: TPanelBevel);
  759. begin
  760.   if Value <> FBevelStyle then begin
  761.     FBevelStyle := Value;
  762.     Sized;
  763.     Update;
  764.   end;
  765. end;
  766.  
  767. procedure TRxCustomSlider.SetOrientation(Value: TSliderOrientation);
  768. begin
  769.   if Orientation <> Value then begin
  770.     FOrientation := Value;
  771.     Sized;
  772.     if ComponentState * [csLoading {$IFDEF WIN32}, csUpdating {$ENDIF}] = [] then
  773.       SetBounds(Left, Top, Height, Width);
  774.   end;
  775. end;
  776.  
  777. procedure TRxCustomSlider.SetOptions(Value: TSliderOptions);
  778. begin
  779.   if Value <> FOptions then begin
  780.     FOptions := Value;
  781.     Invalidate;
  782.   end;
  783. end;
  784.  
  785. procedure TRxCustomSlider.SetRange(Min, Max: Longint);
  786. begin
  787.   if (Min < Max) or (csReading in ComponentState) then begin
  788.     FMinValue := Min;
  789.     FMaxValue := Max;
  790.     if not (csReading in ComponentState) then
  791.       if Min + Increment > Max then FIncrement := Max - Min;
  792.     if (soShowPoints in Options) then Invalidate;
  793.     Self.Value := FValue;
  794.     RangeChanged;
  795.   end;
  796. end;
  797.  
  798. procedure TRxCustomSlider.SetMinValue(Value: Longint);
  799. begin
  800.   if FMinValue <> Value then SetRange(Value, MaxValue);
  801. end;
  802.  
  803. procedure TRxCustomSlider.SetMaxValue(Value: Longint);
  804. begin
  805.   if FMaxValue <> Value then SetRange(MinValue, Value);
  806. end;
  807.  
  808. procedure TRxCustomSlider.SetIncrement(Value: Longint);
  809. begin
  810.   if not (csReading in ComponentState) and ((Value > MaxValue - MinValue) or
  811.     (Value < 1)) then
  812.     raise Exception.CreateFmt(ResStr(SOutOfRange), [1, MaxValue - MinValue]);
  813.   if (Value > 0) and (FIncrement <> Value) then begin
  814.     FIncrement := Value;
  815.     Self.Value := FValue;
  816.     Invalidate;
  817.   end;
  818. end;
  819.  
  820. function TRxCustomSlider.GetValueByOffset(Offset: Integer): Longint;
  821. var
  822.   Range: Double;
  823.   R: TRect;
  824. begin
  825.   R := SliderRect;
  826.   if Orientation = soVertical then
  827.     Offset := ClientHeight - Offset - FImages[siVThumb].Height;
  828.   Range := MaxValue - MinValue;
  829.   Result := Round((Offset - R.Left - Indent) * Range / GetRulerLength);
  830.   if not (soSmooth in Options) then
  831.     Result := Round(Result / Increment) * Increment;
  832.   Result := Min(MinValue + Max(Result, 0), MaxValue);
  833. end;
  834.  
  835. function TRxCustomSlider.GetOffsetByValue(Value: Longint): Integer;
  836. var
  837.   Range: Double;
  838.   R: TRect;
  839.   MinIndent: Integer;
  840. begin
  841.   R := SliderRect;
  842.   Range := MaxValue - MinValue;
  843.   if Orientation = soHorizontal then
  844.     MinIndent := R.Left + Indent
  845.   else
  846.     MinIndent := R.Top + Indent;
  847.   Result := Round((Value - MinValue) / Range * GetRulerLength) + MinIndent;
  848.   if Orientation = soVertical then
  849.     Result := R.Top + R.Bottom - Result - FImages[siVThumb].Height;
  850.   Result := Max(Result, MinIndent);
  851. end;
  852.  
  853. function TRxCustomSlider.GetThumbPosition(var Offset: Integer): TPoint;
  854. var
  855.   R: TRect;
  856.   MinIndent: Integer;
  857. begin
  858.   R := SliderRect;
  859.   if Orientation = soHorizontal then
  860.     MinIndent := R.Left + Indent
  861.   else
  862.     MinIndent := R.Top + Indent;
  863.   Offset := Min(GetOffsetByValue(GetValueByOffset(Min(Max(Offset, MinIndent),
  864.     MinIndent + GetRulerLength))), MinIndent + GetRulerLength);
  865.   if Orientation = soHorizontal then begin
  866.     Result.X := Offset;
  867.     Result.Y := FThumbRect.Top;
  868.   end
  869.   else begin
  870.     Result.Y := Offset;
  871.     Result.X := FThumbRect.Left;
  872.   end;
  873. end;
  874.  
  875. function TRxCustomSlider.GetThumbOffset: Integer;
  876. begin
  877.   if Orientation = soHorizontal then Result := FThumbRect.Left
  878.   else Result := FThumbRect.Top;
  879. end;
  880.  
  881. procedure TRxCustomSlider.InvalidateThumb;
  882. begin
  883.   if HandleAllocated then
  884.     InvalidateRect(Handle, @FThumbRect, not (csOpaque in ControlStyle));
  885. end;
  886.  
  887. procedure TRxCustomSlider.SetThumbOffset(Value: Integer);
  888. var
  889.   ValueBefore: Longint;
  890.   P: TPoint;
  891. begin
  892.   ValueBefore := FValue;
  893.   P := GetThumbPosition(Value);
  894.   InvalidateThumb;
  895.   FThumbRect := Bounds(P.X, P.Y, WidthOf(FThumbRect), HeightOf(FThumbRect));
  896.   InvalidateThumb;
  897.   if FSliding then begin
  898.     FValue := GetValueByOffset(Value);
  899.     if ValueBefore <> FValue then Change;
  900.   end;
  901. end;
  902.  
  903. function TRxCustomSlider.GetRulerLength: Integer;
  904. begin
  905.   if Orientation = soHorizontal then begin
  906.     Result := FRuler.Width;
  907.     Dec(Result, FImages[siHThumb].Width div NumThumbStates);
  908.   end
  909.   else begin
  910.     Result := FRuler.Height;
  911.     Dec(Result, FImages[siVThumb].Height);
  912.   end;
  913. end;
  914.  
  915. procedure TRxCustomSlider.SetValue(Value: Longint);
  916. var
  917.   ValueChanged: Boolean;
  918. begin
  919.   if Value > MaxValue then Value := MaxValue;
  920.   if Value < MinValue then Value := MinValue;
  921.   ValueChanged := FValue <> Value;
  922.   FValue := Value;
  923.   ThumbOffset := GetOffsetByValue(Value);
  924.   if ValueChanged then Change;
  925. end;
  926.  
  927. procedure TRxCustomSlider.SetReadOnly(Value: Boolean);
  928. begin
  929.   if FReadOnly <> Value then begin
  930.     if Value then begin
  931.       StopTracking;
  932.       if FSliding then ThumbMouseUp(mbLeft, [], 0, 0);
  933.     end;
  934.     FReadOnly := Value;
  935.   end;
  936. end;
  937.  
  938. procedure TRxCustomSlider.ThumbJump(Jump: TJumpMode);
  939. var
  940.   NewValue: Longint;
  941. begin
  942.   if Jump <> jmNone then begin
  943.     case Jump of
  944.       jmHome: NewValue := MinValue;
  945.       jmPrior:
  946.         NewValue := (Round(Value / Increment) * Increment) - Increment;
  947.       jmNext:
  948.         NewValue := (Round(Value / Increment) * Increment) + Increment;
  949.       jmEnd: NewValue := MaxValue;
  950.       else Exit;
  951.     end;
  952.     if NewValue >= MaxValue then NewValue := MaxValue
  953.     else if NewValue <= MinValue then NewValue := MinValue;
  954.     if (NewValue <> Value) then Value := NewValue;
  955.   end;
  956. end;
  957.  
  958. function TRxCustomSlider.JumpTo(X, Y: Integer): TJumpMode;
  959. begin
  960.   Result := jmNone;
  961.   if Orientation = soHorizontal then begin
  962.     if FThumbRect.Left > X then Result := jmPrior
  963.     else if FThumbRect.Right < X then Result := jmNext;
  964.   end
  965.   else if Orientation = soVertical then begin
  966.     if FThumbRect.Top > Y then Result := jmNext
  967.     else if FThumbRect.Bottom < Y then Result := jmPrior;
  968.   end;
  969. end;
  970.  
  971. procedure TRxCustomSlider.WMTimer(var Message: TMessage);
  972. begin
  973.   TimerTrack;
  974. end;
  975.  
  976. procedure TRxCustomSlider.CMEnabledChanged(var Message: TMessage);
  977. begin
  978.   inherited;
  979.   InvalidateThumb;
  980. end;
  981.  
  982. procedure TRxCustomSlider.CMFocusChanged(var Message: TCMFocusChanged);
  983. var
  984.   Active: Boolean;
  985. begin
  986.   with Message do Active := (Sender = Self);
  987.   if Active <> FFocused then begin
  988.     FFocused := Active;
  989.     if (soShowFocus in Options) then Invalidate;
  990.   end;
  991.   inherited;
  992. end;
  993.  
  994. procedure TRxCustomSlider.WMGetDlgCode(var Msg: TWMGetDlgCode);
  995. begin
  996.   Msg.Result := DLGC_WANTARROWS;
  997. end;
  998.  
  999. procedure TRxCustomSlider.WMSize(var Message: TWMSize);
  1000. begin
  1001.   inherited;
  1002.   if not (csReading in ComponentState) then Sized;
  1003. end;
  1004.  
  1005. procedure TRxCustomSlider.WMSetCursor(var Message: TWMSetCursor);
  1006. var
  1007.   P: TPoint;
  1008. begin
  1009.   GetCursorPos(P);
  1010.   if not (csDesigning in ComponentState) and PtInRect(FThumbRect,
  1011.     ScreenToClient(P)) then
  1012.   begin
  1013. {$IFDEF WIN32}
  1014.     Windows.SetCursor(Screen.Cursors[crHand]);
  1015. {$ELSE}
  1016.     WinProcs.SetCursor(Screen.Cursors[crHand]);
  1017. {$ENDIF}
  1018.   end
  1019.   else inherited;
  1020. end;
  1021.  
  1022. procedure TRxCustomSlider.StopTracking;
  1023. begin
  1024.   if FTracking then begin
  1025.     if FTimerActive then begin
  1026.       KillTimer(Handle, 1);
  1027.       FTimerActive := False;
  1028.     end;
  1029.     FTracking := False;
  1030.     MouseCapture := False;
  1031.     Changed;
  1032.   end;
  1033. end;
  1034.  
  1035. procedure TRxCustomSlider.TimerTrack;
  1036. var
  1037.   Jump: TJumpMode;
  1038. begin
  1039.   Jump := JumpTo(FMousePos.X, FMousePos.Y);
  1040.   if Jump = FStartJump then begin
  1041.     ThumbJump(Jump);
  1042.     if not FTimerActive then begin
  1043.       SetTimer(Handle, 1, JumpInterval, nil);
  1044.       FTimerActive := True;
  1045.     end;
  1046.   end;
  1047. end;
  1048.  
  1049. procedure TRxCustomSlider.MouseDown(Button: TMouseButton; Shift: TShiftState;
  1050.   X, Y: Integer);
  1051. var
  1052.   Rect: TRect;
  1053.   P: TPoint;
  1054. begin
  1055.   inherited MouseDown(Button, Shift, X, Y);
  1056.   if (Button = mbLeft) and not (ssDouble in Shift) then begin
  1057.     if CanFocus then SetFocus;
  1058.     P := Point(X, Y);
  1059.     if PointInRect(P, FThumbRect) then
  1060.       ThumbMouseDown(Button, Shift, X, Y)
  1061.     else begin
  1062.       with FRulerOrg, FRuler do
  1063.         Rect := Bounds(X, Y, Width, Height);
  1064.       InflateRect(Rect, Ord(Orientation = soVertical) * 3,
  1065.         Ord(Orientation = soHorizontal) * 3);
  1066.       if PointInRect(P, Rect) and CanModify and not ReadOnly then begin
  1067.         MouseCapture := True;
  1068.         FTracking := True;
  1069.         FMousePos := P;
  1070.         FStartJump := JumpTo(X, Y);
  1071.         TimerTrack;
  1072.       end;
  1073.     end;
  1074.   end;
  1075. end;
  1076.  
  1077. procedure TRxCustomSlider.MouseMove(Shift: TShiftState; X, Y: Integer);
  1078. begin
  1079.   if (csLButtonDown in ControlState) and FSliding then
  1080.     ThumbMouseMove(Shift, X, Y)
  1081.   else if FTracking then FMousePos := Point(X, Y);
  1082.   inherited MouseMove(Shift, X, Y);
  1083. end;
  1084.  
  1085. procedure TRxCustomSlider.MouseUp(Button: TMouseButton; Shift: TShiftState;
  1086.   X, Y: Integer);
  1087. begin
  1088.   StopTracking;
  1089.   if FSliding then ThumbMouseUp(Button, Shift, X, Y);
  1090.   inherited MouseUp(Button, Shift, X, Y);
  1091. end;
  1092.  
  1093. procedure TRxCustomSlider.KeyDown(var Key: Word; Shift: TShiftState);
  1094. var
  1095.   Jump: TJumpMode;
  1096. begin
  1097.   Jump := jmNone;
  1098.   if Shift = [] then begin
  1099.     if Key = VK_HOME then Jump := jmHome
  1100.     else if Key = VK_END then Jump := jmEnd;
  1101.     if Orientation = soHorizontal then begin
  1102.       if Key = VK_LEFT then Jump := jmPrior
  1103.       else if Key = VK_RIGHT then Jump := jmNext;
  1104.     end
  1105.     else begin
  1106.       if Key = VK_UP then Jump := jmNext
  1107.       else if Key = VK_DOWN then Jump := jmPrior;
  1108.     end;
  1109.   end;
  1110.   if (Jump <> jmNone) and CanModify and not ReadOnly then begin
  1111.     Key := 0;
  1112.     ThumbJump(Jump);
  1113.     Changed;
  1114.   end;
  1115.   inherited KeyDown(Key, Shift);
  1116. end;
  1117.  
  1118. procedure TRxCustomSlider.ThumbMouseDown(Button: TMouseButton;
  1119.   Shift: TShiftState; X, Y: Integer);
  1120. begin
  1121.   if CanFocus then SetFocus;
  1122.   if (Button = mbLeft) and CanModify and not ReadOnly then begin
  1123.     FSliding := True;
  1124.     FThumbDown := True;
  1125.     if Orientation = soHorizontal then FHit := X - FThumbRect.Left
  1126.     else FHit := Y - FThumbRect.Top;
  1127.     InvalidateThumb;
  1128.     Update;
  1129.   end;
  1130. end;
  1131.  
  1132. procedure TRxCustomSlider.ThumbMouseMove(Shift: TShiftState; X, Y: Integer);
  1133. begin
  1134.   if (csLButtonDown in ControlState) and CanModify and not ReadOnly then
  1135.   begin
  1136.     if Orientation = soHorizontal then ThumbOffset := X - FHit
  1137.     else ThumbOffset := Y - FHit;
  1138.   end;
  1139. end;
  1140.  
  1141. procedure TRxCustomSlider.ThumbMouseUp(Button: TMouseButton;
  1142.   Shift: TShiftState; X, Y: Integer);
  1143. begin
  1144.   if (Button = mbLeft) then begin
  1145.     FSliding := False;
  1146.     FThumbDown := False;
  1147.     InvalidateThumb;
  1148.     Update;
  1149.     if CanModify and not ReadOnly then Changed;
  1150.   end;
  1151. end;
  1152.  
  1153. { TRxCustomTrackBar }
  1154.  
  1155. constructor TRxCustomTrackBar.Create(AOwner: TComponent);
  1156. begin
  1157.   inherited Create(AOwner);
  1158.   FImages := TRxSliderImages.Create;
  1159.   FImages.FSlider := Self;
  1160. end;
  1161.  
  1162. destructor TRxCustomTrackBar.Destroy;
  1163. begin
  1164.   FImages.Free;
  1165.   inherited Destroy;
  1166. end;
  1167.  
  1168. { TRxSliderImages }
  1169.  
  1170. function TRxSliderImages.GetImage(Index: Integer): TBitmap;
  1171. begin
  1172.   Result := FSlider.GetImage(Index);
  1173. end;
  1174.  
  1175. procedure TRxSliderImages.SetImage(Index: Integer; Value: TBitmap);
  1176. begin
  1177.   FSlider.SetImage(Index, Value);
  1178. end;
  1179.  
  1180. function TRxSliderImages.StoreImage(Index: Integer): Boolean;
  1181. begin
  1182.   Result := FSlider.StoreImage(Index);
  1183. end;
  1184.  
  1185. function TRxSliderImages.GetNumThumbStates: TNumThumbStates;
  1186. begin
  1187.   Result := FSlider.NumThumbStates;
  1188. end;
  1189.  
  1190. procedure TRxSliderImages.SetNumThumbStates(Value: TNumThumbStates);
  1191. begin
  1192.   FSlider.NumThumbStates := Value;
  1193. end;
  1194.  
  1195. function TRxSliderImages.GetEdgeSize: Integer;
  1196. begin
  1197.   Result := FSlider.EdgeSize;
  1198. end;
  1199.  
  1200. procedure TRxSliderImages.SetEdgeSize(Value: Integer);
  1201. begin
  1202.   FSlider.EdgeSize := Value;
  1203. end;
  1204.  
  1205. end.
  1206.